import cv2
import numpy as np


def Sobel(img):
    """
    教程看这个链接
    https://blog.csdn.net/sunny2038/article/details/9170013
    :param img: 
    :return: 
    """
    x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
    y = cv2.Sobel(img, cv2.CV_16S, 0, 1)
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)

    dst = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

    cv2.imshow('absX', absX)
    cv2.imshow('absY', absY)

    cv2.imshow('result', dst)


def Laplacian(img):
    gray_lap = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
    dst = cv2.convertScaleAbs(gray_lap)
    cv2.imshow('laplacian', dst)

    # 二级倒数的算法对噪点敏感，所以先进行平滑
    gauss = cv2.GaussianBlur(img, (3, 3), 0)
    gray_lap2 = cv2.Laplacian(gauss, cv2.CV_16S, ksize=3)
    dst2 = cv2.convertScaleAbs(gray_lap2)
    cv2.imshow('laplacian2', dst2)


def Canny(img):
    """
    https://blog.csdn.net/sunny2038/article/details/9202641
    :param img: 
    :return: 
    """
    lowThreshold = 50
    max_lowThreshold = 100
    ratio = 3
    kernel_size = 3

    def CannyThreshold(lowThreshold):
        detected_edges = cv2.GaussianBlur(gray, (3, 3), 0)
        detected_edges = cv2.Canny(detected_edges, lowThreshold, lowThreshold * ratio, apertureSize=kernel_size)
        # dst = cv2.bitwise_and(img, img, mask=detected_edges)
        cv2.imshow("canny demo", detected_edges)

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    cv2.namedWindow('canny demo')
    cv2.createTrackbar('min threshold','canny demo',lowThreshold,max_lowThreshold,CannyThreshold)
    CannyThreshold(lowThreshold)

if __name__ == '__main__':
    img = cv2.imread('imgs/Lena.jpg')
    cv2.imshow('img', img)

    # Sobel算法
    # Sobel(img)
    # sobel = cv2.Sobel(img, -1, 1, 1)
    # absSobel = cv2.convertScaleAbs(sobel)
    # cv2.imshow('sobel',absSobel)

    # Laplace 算法
    # Laplacian(img)

    # Canny算法
    Canny(img)

    cv2.waitKey(0)
    cv2.destroyAllWindows()
